package dj.common.lang.utils;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.StringTokenizer;

/**
 * @author ZJG
 */
@Slf4j
public class ServerHostUtils {

	/**
	 * IP长度
	 */
	private static final int IPLENGTH = 4;

	/**
	 * 获取客户端ip
	 */
	public static String getIp(HttpServletRequest request) {
		String ip = request.getHeader("X-Real-IP");
		String xip = request.getHeader("x-forwarded-for");

		if (!checkIP(ip)) {
			ip = request.getHeader("REMOTE-HOST");
		}

		if (StringUtils.isNotBlank(ip) && !ip.equals(xip)) {
			log.warn("getipne X-Real-IP  " + ip + "    ,x-forwarded-for " + xip);
		}

		if (!checkIP(ip) || !ip.equals(xip)) {
			String info = request.getHeader("x-forwarded-for");
			if (StringUtils.isNotBlank(info)) {
				String[] ips = info.trim().split(",");
				for (String s : ips) {
					//取第一个非unknown的ip地址
					if (!"unknown".equalsIgnoreCase(s)) {
						ip = s;
						break;
					}
				}
			}
		}
		if (!checkIP(ip)) {
			//只在 Apache（Weblogic Plug-In Enable）+WebLogic 搭配下出现
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (!checkIP(ip)) {
			//只在 Apache（Weblogic Plug-In Enable）+WebLogic 搭配下出现
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (!checkIP(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (!checkIP(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (!checkIP(ip)) {
			ip = request.getRemoteAddr();
		}

		// 多级反向代理
		if (null != ip && !"".equals(ip.trim())) {
			StringTokenizer st = new StringTokenizer(ip, ",");
			if (st.countTokens() > 1) {
				log.warn("getip StringTokenizer  " + ip);
				return st.nextToken();
			}
		}
		return ip;
	}

	/**
	 * 验证ip地址格式是否正确
	 *
	 * @param ip
	 * @return
	 * @author lihe 2013-7-4 下午5:26:26
	 * @see
	 */
	private static boolean checkIP(String ip) {
		if (StringUtils.isNotBlank(ip) && ip.split("\\.").length == IPLENGTH) {
			return true;
		}
		return false;
	}
	public static String getIpAddress(HttpServletRequest request) {
		String xip = request.getHeader("X-Real-IP");
		String xfor = request.getHeader("X-Forwarded-For");
		if (org.springframework.util.StringUtils.hasLength(xfor) && !"unKnown".equalsIgnoreCase(xfor)) {
			int index = xfor.indexOf(",");
			if (index != -1) {
				return xfor.substring(0, index);
			} else {
				return xfor;
			}
		}
		xfor = xip;
		if (org.springframework.util.StringUtils.hasLength(xfor) && !"unKnown".equalsIgnoreCase(xfor)) {
			return xfor;
		}
		if (org.springframework.util.StringUtils.hasLength(xfor) || "unknown".equalsIgnoreCase(xfor)) {
			xfor = request.getHeader("Proxy-Client-IP");
		}
		if (org.springframework.util.StringUtils.hasLength(xfor) || "unknown".equalsIgnoreCase(xfor)) {
			xfor = request.getHeader("WL-Proxy-Client-IP");
		}
		if (org.springframework.util.StringUtils.hasLength(xfor) || "unknown".equalsIgnoreCase(xfor)) {
			xfor = request.getHeader("HTTP_CLIENT_IP");
		}
		if (org.springframework.util.StringUtils.hasLength(xfor) || "unknown".equalsIgnoreCase(xfor)) {
			xfor = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (org.springframework.util.StringUtils.hasLength(xfor) || "unknown".equalsIgnoreCase(xfor)) {
			xfor = request.getRemoteAddr();
		}
		return xfor;
	}

	/**
	 * 获取本机服务 ip 地址
	 * @return
	 */
	public static String getHostIp() {
		try{
			Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
			while (allNetInterfaces.hasMoreElements()){
				NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
				Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
				while (addresses.hasMoreElements()){
					InetAddress ip = (InetAddress) addresses.nextElement();
					//loopback地址即本机地址，IPv4的loopback范围是127.0.0.0 ~ 127.255.255.255
					if (ip != null
							&& ip instanceof Inet4Address
							&& !ip.isLoopbackAddress()
							&& ip.getHostAddress().indexOf(":")==-1){
						return ip.getHostAddress();
					}
				}
			}
		}catch(Exception e){
			log.error("getHostIp IP error, ex: {}", e);
		}
		return "127.0.0.1";
	}

	/**
	 * ip 地址转Long
	 * @param ip
	 * @return
	 */
	public static Long getIpNumber(String ip) {
		if (StringUtils.isBlank(ip)
				|| !StringUtils.contains(ip, ".")) {
			return RandomUtils.nextLong();
		}
		Long ipLong = 0L;
		String[] ipNumbers = ip.split("\\.");
		for (String ipNumber : ipNumbers) {
			ipLong = ipLong << 8 | Integer.parseInt(ipNumber);
		}
		return ipLong;
	}

	public static long[] ip2Longs(String ipString) {
		if (ipString == null || ipString.isEmpty()) {
			throw new IllegalArgumentException("ipString cannot be null.");
		}
		String[] ipSlices = ipString.split(":");
		if (ipSlices.length != 8) {
			throw new IllegalArgumentException(ipString + " is not an ipv6 address.");
		}
		long[] ipv6 = new long[2];
		for (int i = 0; i < 8; i++) {
			String slice = ipSlices[i];
			// 以 16 进制解析
			long num = Long.parseLong(slice, 16);
			// 每组 16 位
			long right = num << (16 * i);
			// 每个 long 保存四组，i >> 2 = i / 4
			ipv6[i >> 2] |= right;
		}
		return ipv6;
	}


}
